﻿using LitJson;
using LuoHu.System;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;
using UnityFramework.MVC;
using UnityFramework.Notification;

public class HttpRequestClient : MonoSingleton<HttpRequestClient>
{
    private int timeout = 60;
    /// <summary>
    /// 超时
    /// </summary>
    public int Timeout { get => timeout; set => timeout = value; }
    private int upLoadFileTimeout = 60;

    private const string errorTipStr = "网络错误，请联系管理员";
    private const string tokenTipStr = "登录令牌失效，请重新登录";
    private const string overTimeTipStr = "请求超时，请重试";

    private string m_token = string.Empty;
    private string m_header = string.Empty;
    private string m_urlPrefix = string.Empty;
    private string m_urlPrefix_UploadFile = string.Empty;

    private long TokenUnauthorizedCode = 401;

    public NetInterface NetInterface;
    [HideInInspector]
    public LoginData LoginData;
    private Action<string> loginCallBack;

    public LHLoginData mLHLoginData;
    /// <summary>
    /// 登录专用
    /// </summary>
    /// <param name="userName"></param>
    /// <param name="pw"></param>
    /// <param name="action"></param>
    public void Login(string userName, string pw, Action<string> action)
    {
        if (NetInterface == null)
        {
            Debug.LogError("NetInterface == null ! ");
            action?.Invoke("配置错误");
            //UnityFramework.MVC.SystemMgr.Instance.LHHomeSystem.ShowToastTip("配置错误");
            return;
        }
        NetInterfaceData urlPrefix = NetInterface.dataArray.Single(n => n.Id == 100);
        m_urlPrefix = urlPrefix.Url;
        NetInterfaceData temp = NetInterface.dataArray.Single(n => n.Id == 1000);
        if (temp == null)
        {
            Debug.LogError($"NetInterface can't find index=> {1000} ! ");
            action?.Invoke("表格错误");
            //UnityFramework.MVC.SystemMgr.Instance.LHHomeSystem.ShowToastTip("表格错误");
            return;
        }

        WWWForm form = new WWWForm();
        form.AddField("username", userName);
        form.AddField("password", pw);
        form.AddField("grant_type", "captcha");
        Dictionary<string, string> header = new Dictionary<string, string>();
        string headerStr = string.Empty;
        for (int i = 0; i < temp.Header.Length; i++)
        {
            if ((i & 1) != 1)
            {
                headerStr = temp.Header[i];
            }
            else
            {
                if (temp.Header[i].Contains('@'))
                    header.Add(headerStr, temp.Header[i].Replace('@', ' '));
                else
                    header.Add(headerStr, temp.Header[i]);
            }
        }
        loginCallBack = action;
        StartCoroutine(_PostToken(m_urlPrefix + temp.Url, form, SetToken, header));
    }

    private void SetToken(UnityWebRequest webRequest)
    {
        LoginData = JsonMapper.ToObject<LoginData>(webRequest.downloadHandler.text);
        //JsonData jdata = JsonMapper.ToObject(webRequest.downloadHandler.text);
        if (webRequest.isHttpError || webRequest.isNetworkError)
        {
            if (webRequest.error.Equals("Request timeout"))
            {
                loginCallBack?.Invoke("请求超时");
            }
            else
            {
                //if (jdata == null && jdata["code"] == null)
                //{
                //    loginCallBack?.Invoke("用户名或密码错误");
                //    return;
                //}
                //if (jdata["code"].ToString() == "404" || jdata["code"].ToString() == "500")
                //{
                //    loginCallBack?.Invoke("网络错误");
                //}
                //else
                {
                    loginCallBack?.Invoke("用户名或密码错误");
                }
            }
#if UNITY_EDITOR
            Debug.LogError("webRequest.error：" + webRequest.error + " downloadHandler.text: " + webRequest.downloadHandler.text);
            return;
            if (UnityFramework.MVC.SystemMgr.Instance.LHHomeSystem != null)
            {
                UnityFramework.MVC.SystemMgr.Instance.LHHomeSystem.ShowToastTip(webRequest.error);
            }
            else if (UnityFramework.MVC.SystemMgr.Instance.LHHomeSystem != null)
            {
                UnityFramework.MVC.SystemMgr.Instance.LHHomeSystem.ShowToastTip(webRequest.error);
            }
#endif
        }
        else
        {
            m_token = LoginData.access_token;
            m_header = LoginData.token_type + " " + m_token;
            Debug.Log($"<color=aqua>{LoginData.access_token}</color>");
            loginCallBack?.Invoke(null);
        }
    }

    public void Get<T>(int netIndex, Action<T> action)
    {
        T data = default;
        if (NetInterface == null)
        {
            Debug.LogError("NetInterface == null ! ");
            SystemMgr.Instance.LHHomeSystem.ShowToastTip("配置错误");
            return;
        }
        NetInterfaceData temp;
        try
        {
            temp = NetInterface.dataArray.Single(n => n.Id == netIndex);
        }
        catch (Exception e)
        {
            SystemMgr.Instance.LHHomeSystem.ShowToastTip(e.Message);
            Debug.LogError(e.Message);
            throw;
        }
        if (temp == null)
        {
            Debug.LogError($"NetInterface can't find index=> {netIndex} ! ");
            SystemMgr.Instance.LHHomeSystem.ShowToastTip("参数错误");
            return;
        }

        Dictionary<string, string> header = new Dictionary<string, string>();
        header.Add(temp.Header[0], m_header);
        StartCoroutine(_Get(m_urlPrefix + temp.Url, (web) =>
          {
              if (web.isHttpError || web.isNetworkError)
              {
                  if (web.isNetworkError && web.error.Equals("Request timeout"))//超时提醒
                  {
                      SystemMgr.Instance.LHHomeSystem.ShowToastTip(overTimeTipStr);
                  }
                  else if (web.responseCode == TokenUnauthorizedCode)//token失效重新登录
                  {
                      SystemMgr.Instance.LHHomeSystem.ShowToastTip(tokenTipStr);
                      OnLogOut();
                  }
                  else
                  {
                      SystemMgr.Instance.LHHomeSystem.ShowToastTip(string.Format("{0}\n(code ：{1})", errorTipStr, web.responseCode));
                  }
                  return;
              }
              data = JsonUtility.FromJson<T>(web.downloadHandler.text);
              action?.Invoke(data);
          }, header));
    }

    public void Post<T>(int netIndex, Action<T> action, WWWForm form, bool isEdit = false)
    {
        T data = default;
        if (NetInterface == null)
        {
            Debug.LogError("NetInterface == null ! ");
            SystemMgr.Instance.LHHomeSystem.ShowToastTip("配置错误");
            return;
        }
        NetInterfaceData temp;
        try
        {
            temp = NetInterface.dataArray.Single(n => n.Id == netIndex);
        }
        catch (Exception e)
        {
            SystemMgr.Instance.LHHomeSystem.ShowToastTip(e.Message);
            Debug.LogError(e.Message);
            throw;
        }
        if (temp == null)
        {
            Debug.LogError($"NetInterface can't find index=> {netIndex} ! ");
            SystemMgr.Instance.LHHomeSystem.ShowToastTip("参数错误");
            return;
        }
        Dictionary<string, string> header = new Dictionary<string, string>();
        header.Add(temp.Header[0], m_header);
        if (isEdit)
            SystemMgr.Instance.LHHomeSystem.ShowLoadingTip(LoadingType.Loading);
        StartCoroutine(_Post(m_urlPrefix + temp.Url, form, header, (web) =>
          {
              if (web.isHttpError || web.isNetworkError)
              {
                  if (web.isNetworkError && web.error.Equals("Request timeout"))//超时提醒
                  {
                      if (isEdit)
                          SystemMgr.Instance.LHHomeSystem.ShowLoadingTip(LoadingType.OverTime);
                      else
                          SystemMgr.Instance.LHHomeSystem.ShowToastTip(overTimeTipStr);
                  }
                  else if (web.responseCode == TokenUnauthorizedCode)//token失效重新登录
                  {
                      if (isEdit)
                          SystemMgr.Instance.LHHomeSystem.HideLoadingTip();
                      SystemMgr.Instance.LHHomeSystem.ShowToastTip(tokenTipStr);
                      OnLogOut();
                  }
                  else
                  {
                      if (isEdit)
                      {
                          SystemMgr.Instance.LHHomeSystem.ShowLoadingTip(LoadingType.Failed);
                      }
                      else
                          SystemMgr.Instance.LHHomeSystem.ShowToastTip(string.Format("{0}\n(code ：{1})", errorTipStr, web.responseCode));
                  }
                  return;
              }
              else
              {
                  if (isEdit)
                  {
                      JsonData jsonData = JsonMapper.ToObject(web.downloadHandler.text);
                      if (jsonData != null && jsonData["code"].ToString() == "200")
                      {
                          SystemMgr.Instance.LHHomeSystem.ShowLoadingTip(LoadingType.Success);
                      }
                      else
                      {
                          SystemMgr.Instance.LHHomeSystem.ShowLoadingTip(LoadingType.Failed);
                      }
                  }
              }
              //WriteDebugFile.WriteData("1111", web.downloadHandler.text);
              Debug.Log("<color=green>[ReceiveHttpMsg]</color>" + web.downloadHandler.text);
              data = JsonUtility.FromJson<T>(web.downloadHandler.text);
              action?.Invoke(data);
          }));
    }

    /// <summary>
    /// 上传文件
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="bytes">文件字节</param>
    /// <param name="fileName">文件名</param>
    /// <param name="action">回调</param>
    /// <param name="isEdit"></param>
    public void PostUploadFile<T>(byte[] bytes, string fileName, Action<T> action, bool isEdit = false)
    {
        T data = default;
        if (NetInterface == null)
        {
            Debug.LogError("NetInterface == null ! ");
            SystemMgr.Instance.LHHomeSystem.ShowToastTip("配置错误");
            return;
        }
        if (bytes == null || string.IsNullOrEmpty(fileName))
        {
            Debug.LogError($"PostUploadFile:  bytes==null:{bytes == null}  fileName==null:{string.IsNullOrEmpty(fileName)}");
            return;
        }
        if (string.IsNullOrEmpty(m_urlPrefix_UploadFile))
        {
            if (NetInterface.dataArray.Any(n => n.Id == 110))
            {
                NetInterfaceData nfd = NetInterface.dataArray.SingleOrDefault(n => n.Id == 110);
                m_urlPrefix_UploadFile = nfd.Url;
            }
        }
        NetInterfaceData temp;
        try
        {
            temp = NetInterface.dataArray.Single(n => n.Id == 8888);
        }
        catch (Exception e)
        {
            SystemMgr.Instance.LHHomeSystem.ShowToastTip(e.Message);
            Debug.LogError(e.Message);
            throw;
        }
        if (temp == null)
        {
            Debug.LogError($"NetInterface can't find index=> {8888} ! ");
            SystemMgr.Instance.LHHomeSystem.ShowToastTip("参数错误");
            return;
        }

        Dictionary<string, string> header = new Dictionary<string, string>();
        header.Add(temp.Header[0], m_header);
        if (isEdit)
            SystemMgr.Instance.LHHomeSystem.ShowLoadingTip(LoadingType.Loading);
        var url = m_urlPrefix_UploadFile + temp.Url;

        WWWForm form = new WWWForm();
        form.headers.Add("transfer-encoding", "chunked");
        form.AddBinaryData("file", bytes, fileName, "application/json;charset=UTF-8");
        StartCoroutine(_PostUploadFile(url, form, header, (web) =>
        {
            if (web.isHttpError || web.isNetworkError)
            {
                if (isEdit)
                    SystemMgr.Instance.LHHomeSystem.ShowLoadingTip(LoadingType.Failed);
                else
                    SystemMgr.Instance.LHHomeSystem.ShowToastTip(web.error);
                //token失效重新登录
                if (web.responseCode == TokenUnauthorizedCode)
                {
                    OnLogOut();
                }
                return;
            }
            else
            {
                if (isEdit)
                {
                    JsonData jsonData = JsonMapper.ToObject(web.downloadHandler.text);
                    if (jsonData != null && jsonData["code"].ToString() == "200")
                    {
                        SystemMgr.Instance.LHHomeSystem.ShowLoadingTip(LoadingType.Success);
                    }
                    else
                    {
                        SystemMgr.Instance.LHHomeSystem.ShowLoadingTip(LoadingType.Failed);
                    }
                }
            }
            Debug.Log("<color=green>[ReceiveHttpMsg]</color>" + web.downloadHandler.text);
            data = JsonUtility.FromJson<T>(web.downloadHandler.text);
            action?.Invoke(data);
        }));
    }

    public void PostWhitRawJson<T>(int netIndex, Action<T> action, object dataStruct, bool isEdit = false)
    {
        T data = default;
        if (NetInterface == null)
        {
            Debug.LogError("NetInterface == null ! ");
            SystemMgr.Instance.LHHomeSystem.ShowToastTip("配置错误");
            return;
        }
        NetInterfaceData temp;
        try
        {
            temp = NetInterface.dataArray.Single(n => n.Id == netIndex);
        }
        catch (Exception e)
        {
            SystemMgr.Instance.LHHomeSystem.ShowToastTip(e.Message);
            Debug.LogError(e.Message);
            throw;
        }
        if (temp == null)
        {
            SystemMgr.Instance.LHHomeSystem.ShowToastTip("参数错误");
            Debug.LogError($"NetInterface can't find index=> {netIndex} ! ");
            return;
        }

        Dictionary<string, string> header = new Dictionary<string, string>();
        header.Add(temp.Header[0], m_header);
        if (isEdit)
            SystemMgr.Instance.LHHomeSystem.ShowLoadingTip(LoadingType.Loading);
        StartCoroutine(HttpPost(m_urlPrefix + temp.Url, dataStruct, header, (web) =>
          {
              if (web.isHttpError || web.isNetworkError)
              {
                  if (web.isNetworkError && web.error.Equals("Request timeout"))//超时提醒
                  {
                      if (isEdit)
                          SystemMgr.Instance.LHHomeSystem.ShowLoadingTip(LoadingType.OverTime);
                      else
                          SystemMgr.Instance.LHHomeSystem.ShowToastTip(overTimeTipStr);

                  }
                  else if (web.responseCode == TokenUnauthorizedCode)//token失效重新登录
                  {
                      if (isEdit)
                          SystemMgr.Instance.LHHomeSystem.HideLoadingTip();
                      SystemMgr.Instance.LHHomeSystem.ShowToastTip(tokenTipStr);
                      OnLogOut();
                  }
                  else
                  {
                      if (isEdit)
                          SystemMgr.Instance.LHHomeSystem.ShowLoadingTip(LoadingType.Failed);
                      else
                          SystemMgr.Instance.LHHomeSystem.ShowToastTip(string.Format("{0}\n(code ：{1})", errorTipStr, web.responseCode));
                  }
                  Debug.LogError($"{web.error}");
                  return;
              }
              else
              {
                  if (isEdit)
                  {
                      JsonData jsonData = JsonMapper.ToObject(web.downloadHandler.text);
                      if (jsonData != null && jsonData["code"].ToString() == "200")
                      {
                          SystemMgr.Instance.LHHomeSystem.ShowLoadingTip(LoadingType.Success);
                      }
                      else
                      {
                          SystemMgr.Instance.LHHomeSystem.ShowLoadingTip(LoadingType.Failed);
                      }
                  }
              }
              Debug.Log("<color=green>[ReceiveHttpMsg]</color>" + web.downloadHandler.text);
              data = JsonUtility.FromJson<T>(web.downloadHandler.text);
              action?.Invoke(data);
          }));
    }

    /// <summary>
    /// 只带请求头 header的请求方式
    /// </summary>
    /// <param name="url"></param>
    /// <param name="formfile"></param>
    /// <param name="header"></param>
    /// <param name="action"></param>
    public void Post(string url, WWWForm formfile, Dictionary<string, string> header, Action<UnityWebRequest> action)
    {
        StartCoroutine(_Post(url, formfile, header, action));
    }
    public void Post(string url, List<IMultipartFormSection> lstformData, Dictionary<string, string> header, Action<UnityWebRequest> action)
    {
        StartCoroutine(_Post(url, lstformData, header, action));
    }
    IEnumerator _Post(string url, WWWForm formfile, Dictionary<string, string> header, Action<UnityWebRequest> action)
    {
        UnityWebRequest uwr = UnityWebRequest.Post(url, formfile);
        uwr.timeout = timeout;
        foreach (var item in header.Keys)
        {
            uwr.SetRequestHeader(item, header[item]);
        }
        yield return uwr.SendWebRequest();
        if (uwr.isHttpError || uwr.isNetworkError)
        {
            Debug.LogError($"url: {url}  errorMsg :{uwr.error}");
            action(uwr);
            //MessageWindow.Instance.ShowTipsWin(MessageTips.INTERNET_ERROR);
        }
        else
        {
            if (action != null)
            {
                action(uwr);
            }
            else
            {
                Debug.Log("action is null");
            }
        }
    }
    IEnumerator _PostUploadFile(string url, WWWForm formfile, Dictionary<string, string> header, Action<UnityWebRequest> action)
    {
        UnityWebRequest uwr = UnityWebRequest.Post(url, formfile);
        uwr.timeout = upLoadFileTimeout;
        foreach (var item in header.Keys)
        {
            uwr.SetRequestHeader(item, header[item]);
        }
        yield return uwr.SendWebRequest();
        if (uwr.isHttpError || uwr.isNetworkError)
        {
            Debug.LogError($"url: {url}  errorMsg :{uwr.error}");
            action(uwr);
            //MessageWindow.Instance.ShowTipsWin(MessageTips.INTERNET_ERROR);
        }
        else
        {
            if (action != null)
            {
                action(uwr);
            }
            else
            {
                Debug.Log("action is null");
            }
        }
    }
    IEnumerator _Post(string url, List<IMultipartFormSection> lstformData, Dictionary<string, string> header, Action<UnityWebRequest> action)
    {
        UnityWebRequest uwr = UnityWebRequest.Post(url, lstformData);
        uwr.timeout = timeout;
        foreach (var item in header.Keys)
        {
            uwr.SetRequestHeader(item, header[item]);
        }
        yield return uwr.SendWebRequest();
        if (uwr.isHttpError || uwr.isNetworkError)
        {
            Debug.LogError($"url: {url}  errorMsg :{uwr.error}");
            action(uwr);
            //MessageWindow.Instance.ShowTipsWin(MessageTips.INTERNET_ERROR);
        }
        else
        {
            if (action != null)
            {
                action(uwr);
            }
            else
            {
                Debug.Log("action is null");
            }
        }
    }
    /// <summary>
    /// 带请求头header json/object 的请求
    /// </summary>
    /// <param name="url"></param>
    /// <param name="param"></param>
    /// <param name="actionResult"></param>
    public void PostJson(string url, object param, Dictionary<string, string> header, Action<UnityWebRequest> actionResult)
    {
        StartCoroutine(HttpPost(url, param, header, actionResult));
    }
    public IEnumerator HttpPost(string url, object param, Dictionary<string, string> header, Action<UnityWebRequest> actionResult)
    {
        string jsonParam = JsonMapper.ToJson(param);
        byte[] body = Encoding.UTF8.GetBytes(jsonParam);

        UnityWebRequest unityWeb = new UnityWebRequest(url, "POST");
        unityWeb.timeout = timeout;
        unityWeb.uploadHandler = new UploadHandlerRaw(body);
        if (header != null)
        {
            foreach (var item in header.Keys)
            {
                unityWeb.SetRequestHeader(item, header[item]);
            }
        }

        unityWeb.SetRequestHeader("Content-Type", "application/json;charset=utf-8");
        unityWeb.downloadHandler = new DownloadHandlerBuffer();
        yield return unityWeb.SendWebRequest();
        if (unityWeb.isDone)
        {
            actionResult(unityWeb);
        }
        else
        {
            Debug.Log("Http 请求失败");
            Debug.Log(unityWeb.error);
            actionResult(unityWeb);
        }
    }

    /// <summary>
    /// GET请求
    /// </summary>
    /// <param name="url"></param>
    /// <param name="action"></param>
    public void Get(string url, Action<UnityWebRequest> actionEvents)
    {
        if (string.IsNullOrEmpty(url)) return;
        StartCoroutine(_Get(url, actionEvents));
    }
    /// <summary>
    /// GET请求
    /// </summary>
    /// <param name="url">请求地址,like 'http://www.my-server.com/ '</param>
    /// <param name="action">请求发起后处理回调结果的委托</param>
    /// <returns></returns>
    private IEnumerator _Get(string url, Action<UnityWebRequest> actionEvents)
    {
        using (UnityWebRequest uwr = UnityWebRequest.Get(url))
        {
            uwr.timeout = timeout;
            yield return uwr.SendWebRequest();
            if ((uwr.isNetworkError || uwr.isHttpError))
            {
                Debug.LogError("请求:" + url + " 错误：" + uwr.error);
                if (actionEvents != null) actionEvents(null);
            }
            else
            {
                if (actionEvents != null) actionEvents(uwr);
            }
        }
    }
    #region 下载
    /// <summary>
    /// 下载文件
    /// </summary>
    /// <param name="url">请求地址</param>
    /// <param name="downloadFilePathAndName">储存文件的路径和文件名 like 'Application.persistentDataPath+"/unity3d.html"'</param>
    /// <param name="actionEvents">请求发起后处理回调结果的委托,处理请求对象</param>
    /// <returns></returns>
    public void DownloadFile(string url, string downloadFilePathAndName, Action<UnityWebRequest> actionEvents)
    {
        if (string.IsNullOrEmpty(url)) return;
        StartCoroutine(_DownloadFile(url, downloadFilePathAndName, actionEvents));
    }
    /// <summary>
    /// 下载文件
    /// </summary>
    /// <param name="url">请求地址</param>
    /// <param name="downloadFilePathAndName">储存文件的路径和文件名 like 'Application.persistentDataPath+"/unity3d.html"'</param>
    /// <param name="actionEvents">请求发起后处理回调结果的委托,处理请求对象</param>
    /// <returns></returns>
    private IEnumerator _DownloadFile(string url, string downloadFilePathAndName, Action<UnityWebRequest> actionEvents)
    {
        UnityWebRequest uwr = new UnityWebRequest(url, UnityWebRequest.kHttpVerbGET);
        uwr.timeout = timeout;
        uwr.downloadHandler = new DownloadHandlerFile(downloadFilePathAndName);
        yield return uwr.SendWebRequest();
        if ((uwr.isNetworkError || uwr.isHttpError))
        {
            Debug.LogError("请求:" + url + " 错误：" + uwr.error);
            if (actionEvents != null)
            {
                actionEvents(null);
                SystemMgr.Instance.LHHomeSystem.ShowToastTip(uwr.error);             
            }

        }
        else
        {
            if (actionEvents != null) actionEvents(uwr);
        }
    }

    /// <summary>
    /// 请求图片
    /// </summary>
    /// <param name="url">图片地址,like 'http://www.my-server.com/image.png '</param>
    /// <param name="action">请求发起后处理回调结果的委托,处理请求结果的图片</param>
    /// <returns></returns>
    public void GetTexture(string url, Action<Texture2D> actionEvents)
    {
        if (string.IsNullOrEmpty(url)) return;
        StartCoroutine(_GetTexture(url, actionEvents));
    }
    /// <summary>
    /// 请求图片
    /// </summary>
    /// <param name="url">图片地址,like 'http://www.my-server.com/image.png '</param>
    /// <param name="action">请求发起后处理回调结果的委托,处理请求结果的图片</param>
    /// <returns></returns>
    private IEnumerator _GetTexture(string url, Action<Texture2D> actionEvents)
    {
        UnityWebRequest uwr = new UnityWebRequest(url);
        uwr.timeout = timeout;
        DownloadHandlerTexture downloadTexture = new DownloadHandlerTexture(true);
        uwr.downloadHandler = downloadTexture;
        yield return uwr.SendWebRequest();
        Texture2D t = null;
        if ((uwr.isNetworkError || uwr.isHttpError))
        {
            Debug.LogError("请求:" + url + " 错误：" + uwr.error);
            if (actionEvents != null) actionEvents(null);
        }
        else
        {
            t = downloadTexture.texture;
            if (actionEvents != null) actionEvents(t);
        }
    }

    /// <summary>
    /// 请求AssetBundle
    /// </summary>
    /// <param name="url">AssetBundle地址,like 'http://www.my-server.com/myData.unity3d'</param>
    /// <param name="actionEvents">请求发起后处理回调结果的委托,处理请求结果的AssetBundle</param>
    /// <returns></returns>
    public void GetAssetBundle(string url, Action<AssetBundle> actionEvents)
    {
        if (string.IsNullOrEmpty(url)) return;
        StartCoroutine(_GetAssetBundle(url, actionEvents));
    }
    /// <summary>
    /// 请求AssetBundle
    /// </summary>
    /// <param name="url">AssetBundle地址,like 'http://www.my-server.com/myData.unity3d'</param>
    /// <param name="actionEvents">请求发起后处理回调结果的委托,处理请求结果的AssetBundle</param>
    /// <returns></returns>
    private IEnumerator _GetAssetBundle(string url, Action<AssetBundle> actionEvents)
    {
        UnityWebRequest uwr = new UnityWebRequest(url);
        uwr.timeout = timeout;
        DownloadHandlerAssetBundle handler = new DownloadHandlerAssetBundle(uwr.url, uint.MaxValue);
        uwr.downloadHandler = handler;
        yield return uwr.SendWebRequest();
        AssetBundle bundle = null;
        if ((uwr.isNetworkError || uwr.isHttpError))
        {
            Debug.LogError("请求:" + url + " 错误：" + uwr.error);
            if (actionEvents != null) actionEvents(null);
        }
        else
        {
            bundle = handler.assetBundle;
            if (actionEvents != null) actionEvents(bundle);
        }
    }

    /// <summary>
    /// 请求服务器地址上的音效
    /// </summary>
    /// <param name="url">没有音效地址,like 'http://myserver.com/mysound.wav'</param>
    /// <param name="actionEvents">请求发起后处理回调结果的委托,处理请求结果的AudioClip</param>
    /// <param name="audioType">音效类型</param>
    /// <returns></returns>
    public void GetAudioClip(string url, Action<AudioClip> actionEvents, AudioType audioType = AudioType.WAV)
    {
        if (string.IsNullOrEmpty(url)) return;
        StartCoroutine(_GetAudioClip(url, actionEvents, audioType));
    }
    /// <summary>
    /// 请求服务器地址上的音效
    /// </summary>
    /// <param name="url">没有音效地址,like 'http://myserver.com/mysound.wav'</param>
    /// <param name="actionEvents">请求发起后处理回调结果的委托,处理请求结果的AudioClip</param>
    /// <param name="audioType">音效类型</param>
    /// <returns></returns>
    private IEnumerator _GetAudioClip(string url, Action<AudioClip> actionEvents, AudioType audioType = AudioType.WAV)
    {
        using (var uwr = UnityWebRequestMultimedia.GetAudioClip(url, audioType))
        {
            uwr.timeout = timeout;
            yield return uwr.SendWebRequest();
            if ((uwr.isNetworkError || uwr.isHttpError))
            {
                Debug.LogError("请求:" + url + " 错误：" + uwr.error);
                if (actionEvents != null) actionEvents(null);
            }
            else
            {
                if (actionEvents != null) actionEvents(DownloadHandlerAudioClip.GetContent(uwr));
            }
        }
    }
    #endregion

    /// <summary>
    /// 向服务器提交post请求
    /// </summary>
    /// <param name="serverURL">服务器请求目标地址,like "http://www.my-server.com/myform"</param>
    /// <param name="lstformData">form表单参数</param>
    /// <param name="lstformData">处理返回结果的委托,处理请求对象</param>
    /// <returns></returns>
    public void Post(string serverURL, List<IMultipartFormSection> lstformData, Action<UnityWebRequest> actionEvents)
    {
        //List<IMultipartFormSection> formData = new List<IMultipartFormSection>();
        //formData.Add(new MultipartFormDataSection("field1=foo&field2=bar"));
        //formData.Add(new MultipartFormFileSection("my file data", "myfile.txt"));
        if (string.IsNullOrEmpty(serverURL)) return;
        StartCoroutine(_Post(serverURL, lstformData, actionEvents));
    }
    /// <summary>
    /// 向服务器提交post请求
    /// </summary>
    /// <param name="serverURL">服务器请求目标地址,like "http://www.my-server.com/myform"</param>
    /// <param name="lstformData">form表单参数</param>
    /// <param name="lstformData">处理返回结果的委托</param>
    /// <returns></returns>
    private IEnumerator _Post(string serverURL, List<IMultipartFormSection> lstformData, Action<UnityWebRequest> actionEvents)
    {
        Debug.Log($"send mesg");
        //List<IMultipartFormSection> formData = new List<IMultipartFormSection>();
        //formData.Add(new MultipartFormDataSection("field1=foo&field2=bar"));
        //formData.Add(new MultipartFormFileSection("my file data", "myfile.txt"));
        UnityWebRequest uwr = UnityWebRequest.Post(serverURL, lstformData);
        //uwr.timeout = timeout;
        uwr.SetRequestHeader("Blade-Auth", "bearer " + m_token);
        //uwr.SetRequestHeader("Content-Type", "application/json;charset=UTF-8");
        //uwr.SetRequestHeader("X-Powered-By", "Express");
        uwr.SetRequestHeader("transfer-encoding", "chunked");
        yield return uwr.SendWebRequest();
        if ((uwr.isNetworkError || uwr.isHttpError))
        {
            Debug.LogError("请求:" + serverURL + " 错误：" + uwr.error);
            if (actionEvents != null) actionEvents(null);
        }
        else
        {
            if (actionEvents != null)
                actionEvents(uwr);
        }
    }


    /// <summary>
    /// 通过PUT方式将字节流传到服务器
    /// </summary>
    /// <param name="url">服务器目标地址 like 'http://www.my-server.com/upload' </param>
    /// <param name="contentBytes">需要上传的字节流</param>
    /// <param name="resultAction">处理返回结果的委托</param>
    /// <returns></returns>
    public void UploadByPut(string url, byte[] contentBytes, Action<bool> actionEvents)
    {
        if (string.IsNullOrEmpty(url)) return;
        StartCoroutine(_UploadByPut(url, contentBytes, actionEvents, ""));
    }
    /// <summary>
    /// 通过PUT方式将字节流传到服务器
    /// </summary>
    /// <param name="url">服务器目标地址 like 'http://www.my-server.com/upload' </param>
    /// <param name="contentBytes">需要上传的字节流</param>
    /// <param name="resultAction">处理返回结果的委托</param>
    /// <param name="resultAction">设置header文件中的Content-Type属性</param>
    /// <returns></returns>
    private IEnumerator _UploadByPut(string url, byte[] contentBytes, Action<bool> actionEvents, string contentType = "application/octet-stream")
    {
        UnityWebRequest uwr = new UnityWebRequest(url);
        uwr.timeout = timeout;
        UploadHandler uploader = new UploadHandlerRaw(contentBytes);

        // Sends header: "Content-Type: custom/content-type";
        uploader.contentType = contentType;

        uwr.uploadHandler = uploader;

        yield return uwr.SendWebRequest();

        bool res = true;
        if ((uwr.isNetworkError || uwr.isHttpError))
        {
            Debug.LogError("请求:" + url + " 错误：" + uwr.error);
            if (actionEvents != null) actionEvents(false);
        }
        else
        {
            if (actionEvents != null) actionEvents(res);
        }
    }

    /// <summary>
    /// 带请求头的GET请求
    /// </summary>
    /// <param name="url">请求的地址</param>
    /// <param name="actionResult">请求成功后的回调函数</param>
    /// <param name="header">请求头名</param>
    /// <param name="value">请求头值</param>
    public void Get(string url, Action<UnityWebRequest> actionResult, Dictionary<string, string> header)
    {
        StartCoroutine(_Get(url, actionResult, header));
    }
    /// <summary>
    /// 带请求头的GET请求
    /// </summary>
    /// <param name="url">请求地址</param>
    /// <param name="action">请求发起后处理回调结果的委托</param>
    /// <returns></returns>
    IEnumerator _Get(string url, Action<UnityWebRequest> actionResult, Dictionary<string, string> header)
    {
        using (UnityWebRequest webRequest = UnityWebRequest.Get(url))
        {
            webRequest.timeout = timeout;
            foreach (string item in header.Keys)
                webRequest.SetRequestHeader(item, header[item]);//添加请求头，可能会出错
            yield return webRequest.SendWebRequest();
            if (webRequest.isHttpError || webRequest.isNetworkError)//异常处理
            {
                actionResult?.Invoke(webRequest);
                Debug.LogError("错误信息：" + webRequest.error + " 地址：" + url);
            }
            else
            {
                Debug.Log("收到地址：" + url + "  的反馈信息：" + webRequest.downloadHandler.text);
                actionResult?.Invoke(webRequest);
            }
        }
    }


    /// <summary>
    ///  向服务器提交post请求
    /// </summary>
    /// <param name="serverURL">Post地址</param>
    /// <param name="formData">WWWForm 参数表单</param>
    /// <param name="actionResult">post成功后的回调函数</param>
    public void Post(string url, WWWForm formData, Action<UnityWebRequest> actionResult)
    {
        StartCoroutine(_Post(url, formData, actionResult));
    }
    /// <summary>
    ///  向服务器提交post请求
    /// </summary>
    /// <param name="serverURL">Post地址</param>
    /// <param name="formFields"> Dictionary<string, string> 参数表单</param>
    /// <param name="actionResult">post成功后的回调函数</param>
    public void Post(string url, Dictionary<string, string> formFields, Action<UnityWebRequest> actionResult)
    {
        StartCoroutine(_Post(url, formFields, actionResult));
    }


    /// <summary>
    ///  向服务器提交post请求 带请求头
    /// </summary>
    /// <param name="serverURL">Post地址</param>
    /// <param name="formData"> WWWForm参数表单</param>
    /// <param name="actionResult">post成功后的回调函数</param>
    public void Post(string url, WWWForm formData, Action<UnityWebRequest> actionResult, Dictionary<string, string> header)
    {
        StartCoroutine(_Post(url, formData, actionResult, header));
    }
    /// <summary>
    ///  向服务器提交post请求 带请求头
    /// </summary>
    /// <param name="serverURL">Post地址</param>
    /// <param name="formFields">Dictionary<string, string> 参数表单</param>
    /// <param name="actionResult">post成功后的回调函数</param>
    public void Post(string url, Dictionary<string, string> formFields, Action<UnityWebRequest> actionResult, Dictionary<string, string> header)
    {
        StartCoroutine(_Post(url, formFields, actionResult, header));
    }


    /// <summary>
    /// 向服务器提交post请求
    /// </summary>
    /// <param name="serverURL">服务器请求目标地址"</param>
    /// <param name="lstformData">form表单参数</param>
    /// <param name="lstformData">处理返回结果的委托</param>
    /// <returns></returns>
    IEnumerator _Post(string url, WWWForm formData, Action<UnityWebRequest> actionResult)
    {
        using (UnityWebRequest webRequest = UnityWebRequest.Post(url, formData))
        {
            webRequest.timeout = timeout;
            webRequest.SetRequestHeader("Blade-Auth", "bearer " + m_token);
            webRequest.SetRequestHeader("Content-Type", "application/json;charset=UTF-8");
            //uwr.SetRequestHeader("X-Powered-By", "Express");
            webRequest.SetRequestHeader("transfer-encoding", "chunked");
            yield return webRequest.SendWebRequest();
            if (webRequest.isHttpError || webRequest.isNetworkError)//异常处理
            {
                actionResult(null);
                Debug.LogError("错误信息：" + webRequest.error + " 地址：" + url);
            }
            else
            {
                Debug.Log("收到地址：" + url + "  的反馈信息：" + webRequest.downloadHandler.text);
                if (actionResult != null) actionResult(webRequest);
            }
        }
    }
    /// <summary>
    /// 向服务器提交post请求
    /// </summary>
    /// <param name="serverURL">服务器请求目标地址"</param>
    /// <param name="lstformData">form表单参数</param>
    /// <param name="lstformData">处理返回结果的委托</param>
    /// <returns></returns>
    IEnumerator _Post(string url, Dictionary<string, string> formField, Action<UnityWebRequest> actionResult)
    {
        using (UnityWebRequest webRequest = UnityWebRequest.Post(url, formField))
        {
            webRequest.timeout = timeout;
            yield return webRequest.SendWebRequest();
            if (webRequest.isHttpError || webRequest.isNetworkError)//异常处理
            {
                actionResult(null);
                Debug.LogError("错误信息：" + webRequest.error + " 地址：" + url);
            }
            else
            {
                Debug.Log("收到地址：" + url + "  的反馈信息：" + webRequest.downloadHandler.text);
                if (actionResult != null) actionResult(webRequest);
            }
        }
    }

    /// <summary>
    /// 向服务器提交post请求 带请求头
    /// </summary>
    /// <param name="serverURL">服务器请求目标地址"</param>
    /// <param name="lstformData">form表单参数</param>
    /// <param name="lstformData">处理返回结果的委托</param>
    /// <returns></returns>
    IEnumerator _Post(string url, WWWForm formData, Action<UnityWebRequest> actionResult, Dictionary<string, string> header)
    {
        using (UnityWebRequest webRequest = UnityWebRequest.Post(url, formData))
        {
            webRequest.timeout = timeout;
            foreach (string item in header.Keys) webRequest.SetRequestHeader(item, header[item]);//添加请求头，可能会出错
            yield return webRequest.SendWebRequest();
            if (webRequest.isHttpError || webRequest.isNetworkError)//异常处理
            {
                Debug.LogError(webRequest.error);
                actionResult(null);
                Debug.Log("错误信息：" + webRequest.error + " 地址：" + url);
            }
            else
            {
                Debug.Log("收到地址：" + url + "  的反馈信息：" + webRequest.downloadHandler.text);
                if (actionResult != null) actionResult(webRequest);
            }
        }
    }
    /// <summary>
    /// 向服务器提交post请求 带请求头
    /// </summary>
    /// <param name="serverURL">服务器请求目标地址"</param>
    /// <param name="lstformData">form表单参数</param>
    /// <param name="lstformData">处理返回结果的委托</param>
    /// <returns></returns>
    IEnumerator _Post(string url, Dictionary<string, string> formField, Action<UnityWebRequest> actionResult, Dictionary<string, string> header)
    {
        using (UnityWebRequest webRequest = UnityWebRequest.Post(url, formField))
        {
            webRequest.timeout = timeout;
            foreach (string item in header.Keys) webRequest.SetRequestHeader(item, header[item]);//添加请求头，可能会出错
            yield return webRequest.SendWebRequest();
            if (webRequest.isHttpError || webRequest.isNetworkError)//异常处理
            {
                actionResult(null);
                Debug.Log("错误信息：" + webRequest.error + " 地址：" + url);
            }
            else
            {
                Debug.Log("收到地址：" + url + "  的反馈信息：" + webRequest.downloadHandler.text);
                if (actionResult != null) actionResult(webRequest);
            }


        }
    }

    /// <summary>
    /// 获取Token专用
    /// </summary>
    /// <param name="url"></param>
    /// <param name="formData"></param>
    /// <param name="actionResult"></param>
    /// <param name="header"></param>
    /// <returns></returns>
    IEnumerator _PostToken(string url, WWWForm formData, Action<UnityWebRequest> actionResult, Dictionary<string, string> header)
    {
        using (UnityWebRequest webRequest = UnityWebRequest.Post(url, formData))
        {
            webRequest.timeout = timeout;
            foreach (string item in header.Keys) webRequest.SetRequestHeader(item, header[item]);//添加请求头，可能会出错
            yield return webRequest.SendWebRequest();
            actionResult?.Invoke(webRequest);
        }
    }

    private async void OnLogOut()
    {
        if (zFrame.Networks.NetworkClient.isConnected)
            zFrame.Networks.NetworkClient.Instance.CloseSocket();
        SystemNotifyArg arg = new SystemNotifyArg();
        arg.System = typeof(LHHomeSystem);
        arg.SystemName = typeof(LHHomeSystem).Name;
        NotificationManager.Instance.Send(NotifyIds.SYSTEM_CHANGE, arg);
    }
}

#region 登录数据
[Serializable]
public class LoginData
{
    public string access_token;
    public string token_type;
    public string refresh_token;
    public int expires_in;
    public string scope;
    public string tenant_id;
    public string role_name;
    public string license;
    public string user_id;
    public string role_id;
    public string user_name;
    public string nick_name;
    public string real_name;
    public string avatar;
    public string dept_id;
    public string client_id;
    public string account;
    public string jti;
}

[System.Serializable]
public class LHLoginData
{
    public string phone;
    public string reakName;
    public bool islogisucess;
}
#endregion
